﻿using System;
using System.Collections.Generic;
// using System.Linq;
using System.Text;
using System.Drawing;

namespace IntelliTouchMix
{
    public class Point2f 
    {
        public float x, y;
        public Point2f() { }
        public Point2f(float x, float y)
        {
            this.x = x;
            this.y = y;
        }

        internal static Size add(Point2f p1, Size p2)
        {
            p2.Width += (int)p1.x;
            p2.Height += (int)p1.y;
            return p2;
        }
        public static Point add(Point2f p1, Point p2)
        {
            p2.X += (int)p1.x;
            p2.Y += (int)p1.y;
            return p2;
        }
        public static PointF[] toPointF(Point2f[] v)
        {
            PointF[] f = new PointF[v.Length];
            for (int i = 0; i < v.Length; ++i)
            {
                f[i].X = v[i].x;
                f[i].Y = v[i].y;
            }
            return (PointF[])f;
        }
        public void add(int x2, int y2)
        {
            x += x2;
            y += y2;
        }
        public void add(Point2f v)
        {
            x += v.x;
            y += v.y;
        }

        public float getAngleFromVector(Point2f v)
        {
            return (180.0f/(float)Math.PI)*(float)Math.Acos((double)(x * v.x + y * v.y)/(dist()*v.dist()) );
        }
        public float getAngleFromVectorRad(Point2f v)
        {
            return (float)Math.Cos((double)(x * v.x + y * v.y));
        }
        public float dot(Point2f v)
        {
            return x * v.x + y * v.y;
        }
        // return the distance between points
        public float dist2(Point2f v)
        {
            Point2f d = sub(v);
            return d.dist2();
        }
        public float dist2()
        {
            return x * x + y * y;
        }
        internal float dist2(Size s)
        {

            Point2f d = sub(s);
            return d.dist2();
        }
        internal float dist2(Point l)
        {
            Point2f d = sub(l);
            return d.dist2();

        }
        private Point2f sub(Size l)
        {
            return new Point2f(x - l.Width, y - l.Height);
        }
        private Point2f sub(Point l)
        {
            return new Point2f(x - l.X, y - l.Y);
        }
        public float dist()
        {
            return (float)Math.Sqrt( x * x + y * y);
        }
        public Point2f sub(Point2f p)
        {
            Point2f r = new Point2f(x-p.x,y-p.y);
            return r;
        }
        public void normalize(float n)
        {
            x /= n;
            y /= n;
        }
        public void normalize()
        {
            float n = (float)Math.Sqrt((float)dist2());
            x /= n;
            y /= n;
        }
        public override String ToString()
        {
            return "(" + x + "," + y + ")";
        }



        
    }
    class Point2i
    {
        public int x, y;
        public Point2i(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
        public void max(int x2, int y2)
        {
            x = Math.Max(x, x2);
            y = Math.Max(y, y2);
        }
        public void min(int x2, int y2)
        {
            x = Math.Min(x, x2);
            y = Math.Min(y, y2);
        }

        public override String ToString()
        {
            return "(" + x + "," + y + ")";
        }

        internal void set(int p, int p_2)
        {
            x = p;
            y = p_2;
        }
    }
    class CircularIndex
    {
        int mask;
        int i;
        public CircularIndex(int m) { mask = m; }
        public int value
        {
            set { i = value; }
        }
        public int next
        {
            get
            {
                i++;
                return mask & i;
            }
        }
    }
 
}
